//! 错误处理模块
//! 
//! 提供统一的错误类型和处理机制

use serde::{Deserialize, Serialize};
use std::fmt;

/// Binance SDK错误类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BinanceError {
    /// 网络错误
    NetworkError(String),
    /// HTTP错误
    HttpError(u16, String),
    /// API错误
    ApiError(BinanceApiError),
    /// 配置错误
    ConfigError(String),
    /// 序列化错误
    SerializationError(String),
    /// 解析错误
    ParseError(String),
    /// 其他错误
    Other(String),
}

/// Binance API错误响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BinanceApiError {
    pub code: i32,
    pub msg: String,
}

impl fmt::Display for BinanceError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            BinanceError::NetworkError(msg) => write!(f, "Network error: {}", msg),
            BinanceError::HttpError(code, msg) => write!(f, "HTTP {} error: {}", code, msg),
            BinanceError::ApiError(api_err) => write!(f, "API error {}: {}", api_err.code, api_err.msg),
            BinanceError::ConfigError(msg) => write!(f, "Configuration error: {}", msg),
            BinanceError::SerializationError(msg) => write!(f, "Serialization error: {}", msg),
            BinanceError::ParseError(msg) => write!(f, "Parse error: {}", msg),
            BinanceError::Other(msg) => write!(f, "Other error: {}", msg),
        }
    }
}

impl std::error::Error for BinanceError {}

/// 结果类型别名
pub type Result<T> = std::result::Result<T, BinanceError>;

/// 从reqwest错误转换
impl From<reqwest::Error> for BinanceError {
    fn from(err: reqwest::Error) -> Self {
        BinanceError::NetworkError(err.to_string())
    }
}

/// 从serde_json错误转换
impl From<serde_json::Error> for BinanceError {
    fn from(err: serde_json::Error) -> Self {
        BinanceError::SerializationError(err.to_string())
    }
}

/// 从std::io错误转换
impl From<std::io::Error> for BinanceError {
    fn from(err: std::io::Error) -> Self {
        BinanceError::Other(err.to_string())
    }
}

/// 从tokio_tungstenite错误转换
impl From<tokio_tungstenite::tungstenite::Error> for BinanceError {
    fn from(err: tokio_tungstenite::tungstenite::Error) -> Self {
        BinanceError::NetworkError(err.to_string())
    }
}

/// 从url错误转换
impl From<url::ParseError> for BinanceError {
    fn from(err: url::ParseError) -> Self {
        BinanceError::ConfigError(err.to_string())
    }
}

/// 从anyhow错误转换
impl From<anyhow::Error> for BinanceError {
    fn from(err: anyhow::Error) -> Self {
        BinanceError::Other(err.to_string())
    }
}

/// 错误处理工具函数
impl BinanceError {
    /// 检查是否为网络错误
    pub fn is_network_error(&self) -> bool {
        matches!(self, BinanceError::NetworkError(_))
    }

    /// 检查是否为API错误
    pub fn is_api_error(&self) -> bool {
        matches!(self, BinanceError::ApiError(_))
    }

    /// 检查是否为配置错误
    pub fn is_config_error(&self) -> bool {
        matches!(self, BinanceError::ConfigError(_))
    }

    /// 获取错误消息
    pub fn message(&self) -> &str {
        match self {
            BinanceError::NetworkError(msg) => msg,
            BinanceError::HttpError(_, msg) => msg,
            BinanceError::ApiError(api_err) => &api_err.msg,
            BinanceError::ConfigError(msg) => msg,
            BinanceError::SerializationError(msg) => msg,
            BinanceError::ParseError(msg) => msg,
            BinanceError::Other(msg) => msg,
        }
    }

    /// 获取API错误代码
    pub fn api_code(&self) -> Option<i32> {
        match self {
            BinanceError::ApiError(api_err) => Some(api_err.code),
            _ => None,
        }
    }
}

/// 常见错误代码常量
pub mod error_codes {
    /// 未知订单
    pub const UNKNOWN_ORDER: i32 = -2011;
    /// 余额不足
    pub const INSUFFICIENT_BALANCE: i32 = -2010;
    /// 无效符号
    pub const INVALID_SYMBOL: i32 = -1121;
    /// 无效数量
    pub const INVALID_QUANTITY: i32 = -1013;
    /// 无效价格
    pub const INVALID_PRICE: i32 = -1013;
    /// 请求过于频繁
    pub const TOO_MANY_REQUESTS: i32 = -1003;
    /// 请求被限制
    pub const REQUEST_THROTTLED: i32 = -1008;
    /// 无效API密钥
    pub const INVALID_API_KEY: i32 = -1022;
    /// 签名验证失败
    pub const INVALID_SIGNATURE: i32 = -1021;
    /// 时间戳过期
    pub const TIMESTAMP_EXPIRED: i32 = -1021;
}
